﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
using Supermarket.Data;
using SupermarketModel;
using System.Globalization;

namespace Supermarket.Client
{
    static class PDFReporter
    {
        public static void GenerateReport(string path)
        {
            using(Document document = new Document())
            {
                PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(path, FileMode.Create));
                using(SupermarketContext database = new SupermarketContext())
	            {
                    Font boldFont = new Font(Font.FontFamily.HELVETICA, 9, Font.NORMAL, BaseColor.BLACK);
                    Font normalFont = new Font(Font.FontFamily.HELVETICA, 9, Font.NORMAL, BaseColor.BLACK);
                    Font headerFont = new Font(Font.FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.BLACK);
                    document.Open();
                    AddParagraph(document, headerFont, new Chunk("Aggregate Report"));
                    PdfPTable table = new PdfPTable(5);
                    table.SetWidths(new float[] { 1.8f, 1.0f, 1.2f, 2.7f, 0.8f });

                    // Query
                    DateTime lastDate = new DateTime(0);
                    var reports = GetReport(database);
                    decimal currentSum = 0m;
                    bool firstLine = true;
                    foreach (var report in reports)
                    {
                        if (!report.ReportDate.Equals(lastDate))
                        {
                            if (!firstLine)
                            {
                                AddFooter(table, lastDate, currentSum, normalFont);
                            }
                            AddHeadings(table, report.ReportDate, normalFont);
                            currentSum = 0m;
                        }
                        AddRow(table, report, normalFont);
                        lastDate = report.ReportDate;
                        currentSum += report.Sum;
                        firstLine = false;
                    }

                    if (!firstLine)
                    {
                        AddFooter(table, lastDate, currentSum, normalFont);
                    }

                    document.Add(table);
	            }
            }
        }

        private static void AddFooter(PdfPTable table, DateTime date, decimal totalSum, Font font)
        {
            PdfPHeaderCell total = new PdfPHeaderCell();
            total.Colspan = 4;
            total.HorizontalAlignment = Element.ALIGN_RIGHT;
            string dateAsString = date.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture);
            Paragraph text = new Paragraph(new Chunk("Total sum for " + dateAsString + ":", font));
            text.Alignment = Element.ALIGN_RIGHT;
            total.AddElement(text);
            table.AddCell(total);

            PdfPHeaderCell sum = new PdfPHeaderCell();
            sum.VerticalAlignment = Element.ALIGN_MIDDLE;
            sum.AddElement(new Chunk(totalSum.ToString(), font));
            table.AddCell(sum);
        }

        private static void AddHeadings(PdfPTable table, DateTime date, Font font)
        {
            PdfPCell cell = new PdfPCell();
            cell.Colspan = 5;
            cell.BackgroundColor = BaseColor.LIGHT_GRAY;
            string dateAsString = date.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture);
            cell.AddElement(new Chunk("Date: " + dateAsString, font));
            table.AddCell(cell);

            Font boldFont = FontFactory.GetFont(FontFactory.HELVETICA_BOLD, 9);

            PdfPCell products = new PdfPCell();
            products.HorizontalAlignment = Element.ALIGN_CENTER;
            products.AddElement(new Phrase("Product", boldFont));
            products.BackgroundColor = BaseColor.LIGHT_GRAY;
            table.AddCell(products);

            PdfPHeaderCell quantity = new PdfPHeaderCell();
            quantity.AddElement(new Chunk("Quantity", boldFont));
            quantity.BackgroundColor = BaseColor.LIGHT_GRAY;
            table.AddCell(quantity);

            PdfPHeaderCell unitPrice = new PdfPHeaderCell();
            unitPrice.AddElement(new Chunk("Unit Price", boldFont));
            unitPrice.BackgroundColor = BaseColor.LIGHT_GRAY;
            table.AddCell(unitPrice);

            PdfPHeaderCell location = new PdfPHeaderCell();
            location.AddElement(new Chunk("Location", boldFont));
            location.BackgroundColor = BaseColor.LIGHT_GRAY;
            table.AddCell(location);

            PdfPHeaderCell sum = new PdfPHeaderCell();
            sum.AddElement(new Chunk("Sum", boldFont));
            sum.BackgroundColor = BaseColor.LIGHT_GRAY;
            table.AddCell(sum);
        }

        private static void AddRow(PdfPTable table, PDFSalesReport report, Font font)
        {
            PdfPCell product = new PdfPCell(new Phrase(report.Product, font));
            PdfPCell quantity = new PdfPCell(new Phrase(report.Quantity, font));
            PdfPCell unitPrice = new PdfPCell(new Phrase(report.UnitPrice.ToString(), font));
            PdfPCell location = new PdfPCell(new Phrase(report.Location, font));
            PdfPCell sum = new PdfPCell(new Phrase(report.Sum.ToString(), font));
            table.AddCell(product);
            table.AddCell(quantity);
            table.AddCell(unitPrice);
            table.AddCell(location);
            table.AddCell(sum);
        }

        private static IEnumerable<PDFSalesReport> GetReport(SupermarketContext database)
        {
            IEnumerable<PDFSalesReport> elements = database.Database.SqlQuery<PDFSalesReport>(@"SELECT p.Name AS Product, CONVERT(nvarchar, SUM(sr.Quantity)) + ' ' + me.Name AS Quantity, p.BasePrice AS [UnitPrice], m.Name AS Location, SUM(sr.Sum) AS Sum, sr.ReportDate FROM SalesReports sr
              JOIN Products p ON sr.ProductId = p.ID
              JOIN Markets m ON sr.MarketId = m.Id
              JOIN Measures me ON p.MeasureID = me.ID
              GROUP BY p.Name, m.Name, p.BasePrice, me.Name, sr.ReportDate
			  ORDER BY sr.ReportDate");
              return elements;
        }

        private static void AddParagraph(Document document, Font font, IElement content)
        {
            //AddParagraph(document, font, Element.ALIGN_CENTER, new Chunk("just mama a simple content"));
            Paragraph paragraph = new Paragraph();
            paragraph.SetLeading(0f, 1.2f);
            paragraph.Alignment = Element.ALIGN_CENTER;
            paragraph.Font = font;
            paragraph.SpacingAfter = 20;
            paragraph.Add(content);
            document.Add(paragraph);
        }
    }
}
